#pragma once

#include "TrTypes.h"
#include "TrSingleton.h"
#include <QtCore/QVector>
#include <QtCore/QString>
#include <QtCore/QTime>
#include <QtCore/QDateTime>
#include <QtCore/QMap>
#include <vector>

namespace Market {

struct TimeRange
{
    uint32_t start;
    uint32_t end;
};

class TrSession : public TrSingleton<TrSession>
{
    friend class TrSingleton<TrSession>;
public:
    TrSession(const TrSession&) = delete;
    TrSession& operator=(const TrSession&) = delete;
public:
    static QVector<QString> TimeNode(TrPeriod period, const std::vector<TimeRange>& range);
    static QVector<QString> Get(const QString& name, TrPeriod period);

    bool isInTradingTime(const QString& name, qint64 timestamp) const;
    bool isInTradingTime(const QString& name, const QTime& time) const;
    
    QDateTime getBarStartTime(const QString& name, TrPeriod period, const QDateTime& time) const;
    QDateTime getNextBarTime(const QString& name, TrPeriod period, const QDateTime& time) const;
    
    std::vector<TimeRange> getTradingRanges(const QString& name) const;
    
    static uint32_t timeToNumber(const QTime& time);
    static QTime numberToTime(uint32_t timeNum);
    static bool isCrossDay(uint32_t startTime, uint32_t endTime);
protected:
    TrSession();
private:
    bool isTimeInRange(uint32_t timeNum, const TimeRange& range) const;
    uint32_t normalizeTimeNumber(uint32_t timeNum) const;
    QMap<QString, std::vector<TimeRange>> m_tradingRanges;
};

#define SESSION Market::TrSession::instance()
} // namespace Market